package org.bwapi.unit.client;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import org.bwapi.bridge.BridgeBot;
import org.bwapi.bridge.BridgeBotFactory;
import org.bwapi.bridge.model.Game;
import org.bwapi.unit.server.BwapiBridgeBotServer;

/**
 * Factory used for connecting to RMI and loading the test bot
 * 
 * @author Chad Retz
 */
public class BwapiTestBotFactory implements BridgeBotFactory {
	
	@Override
	public BridgeBot getBridgeBot(Game game) {
		//first I gotta connect to the server
		Registry registry;
		try {
			registry = LocateRegistry.getRegistry(BwapiBridgeBotServer.PORT);
		} catch (Exception e) {
			game.printf("Unable to connect: " + e.getMessage());
			return null;
		}
		final BwapiBridgeBotServer server;
		try {
			server = (BwapiBridgeBotServer) registry.lookup(BwapiBridgeBotServer.NAME);
		} catch (Exception e) {
			game.printf("Unable to find server: " + e.getMessage());
			return null;
		}
		final BridgeBot bot;
		try {
			bot = (BridgeBot) Class.forName(server.getBridgeBotClass()).newInstance();
		} catch (Exception e) {
			game.printf("Unable to instantiate bot: " + e.getMessage());
			return null;
		}
		return new BridgeBot() {
			private boolean failed = false;
			@Override
			public void onStart() {
				if (!failed) {
					try {
						bot.onStart();
					} catch (Throwable e) {
						failed = true;
						try {
							server.onError(e);
						} catch (RemoteException re) {
							//who cares...
						}
					}
				}
			}
			
			@Override
			public boolean onSendText(String string) {
				if (!failed) {
					try {
						return bot.onSendText(string);
					} catch (Throwable e) {
						failed = true;
						try {
							server.onError(e);
						} catch (RemoteException re) {
							//who cares...
						}
					}
				}
				return true;
			}
			
			@Override
			public void onFrame() {
				if (!failed) {
					try {
						bot.onFrame();
					} catch (Throwable e) {
						failed = true;
						try {
							server.onError(e);
						} catch (RemoteException re) {
							//who cares...
						}
					}
				}
			}
			
			@Override
			public void onEnd() {
				if (!failed) {
					try {
						bot.onEnd();
					} catch (Throwable e) {
						failed = true;
						try {
							server.onError(e);
						} catch (RemoteException re) {
							//who cares...
						}
					}
					try {
						server.onEnd();
					} catch (RemoteException e) {
						// who cares...
					}
				}
			}
		};
	}

}
